package znzz.core.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import znzz.core.dao.IBaseMapper;
import znzz.core.entity.BaseVO;
import znzz.core.service.ISyncService;
import znzz.db.dao.icommon.ISubBaseVOMapper;
import znzz.db.entity.ParamVO;
import znzz.db.util.BeanUtil;
import znzz.db.util.MongoDBUtil;
import znzz.db.util.TableAndAttrUtil;
import znzz.db.util.constant.SyncConst;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 同步数据服务
 * <p/>
 * Created by wangjwm on 2017/7/6.
 */
public abstract class SyncServiceImpl implements ISyncService {

    @Autowired
    @Qualifier("tableAndAttrUtil")
    private TableAndAttrUtil tableAndAttrUtil;

    public abstract IBaseMapper getBaseMapper();

    public abstract Map<String, IBaseMapper> getSubMappers();

    private void tablesDeal(String tableName, boolean isSubVO) {
        IBaseMapper iBaseMapper = null;
        if (isSubVO) {
            iBaseMapper = this.getSubMappers().get(tableName.split("_")[2]);
        } else {
            iBaseMapper = this.getBaseMapper();
        }
        iBaseMapper.createTable(tableName);
        iBaseMapper.clearTable(tableName);
    }

    public int syncDocuments(String tableName) {
        // 获得子表名称
        List<String> subTables = tableAndAttrUtil.getTable2Sub().get(tableName);
        String trueTableName = SyncConst.TABLE_PREFIX + tableName;
        // 1.create if not exist 2.如果有表清空
        tablesDeal(trueTableName, false);
        if (subTables != null) {
            for (int i = 0; i < subTables.size(); i++) {
                tablesDeal(trueTableName + "_" + subTables.get(i), true);
            }
        }
        int size = 0;
        // 3.获得Documents
        long startTime = System.currentTimeMillis();
        String dbName = MongoDBUtil.instance.getMongoConfigVO().getCollectionname();
        MongoCollection<Document> barcodeMasterColl = MongoDBUtil.instance.getCollection(dbName, tableName);
        long count = barcodeMasterColl.count();
        // 4.执行分页查询
        int page = (new Long(count).intValue() / SyncConst.SYNC_NUM_NORMAL_MAX) + 1;
        for (int i = 1; i <= page; i++) {
            List<BaseVO> list = new ArrayList<BaseVO>();
            // 4.1. 获得Documents（一次100条）
            MongoCursor<Document> iterator = MongoDBUtil.instance.findByPage(barcodeMasterColl, i, SyncConst.SYNC_NUM_NORMAL_MAX);
            while (iterator.hasNext()) {
                // 4.2 循环每条记录，将其转换为JSON
                Document document = iterator.next();
                JSONObject obj = JSONObject.parseObject(document.toJson());
                // 4.2 缓存主键（无论主子表都有主键）
                // 4.3 获得主表的VO
                // if("573d15227844502ab4b13185".equals(document.get("_id").toString())) {
                    System.out.println("表名：" + tableName + "；" + "主键值：" + document.get("_id").toString());
                    ParamVO paramVO = new ParamVO();
                    paramVO.setCommonSubVO(false);
                    paramVO.setTableName(tableName);
                    list.add(BeanUtil.document2Bean(document, null, paramVO));
                    if (subTables != null) {
                        // 4.4 如果包含子类，单独执行子类insert
                        for (String subTable : subTables) {
                            if (obj.containsKey(subTable)) {
                                List<Object> subDocuments = (List<Object>) document.get(subTable);
                                IBaseMapper iBaseMapper = this.getSubMappers().get(subTable);
                                paramVO.setCommonSubVO(iBaseMapper instanceof ISubBaseVOMapper);
                                paramVO.setSubTableName(subTable);
                                List<? extends BaseVO> subBaseVOs = BeanUtil.subDocument2Bean(document, subDocuments, paramVO);
                                System.out.println(subBaseVOs.size());
                                if (subBaseVOs.size() > 0) {
                                    iBaseMapper.insertByBatch(trueTableName + "_" + subTable, subBaseVOs);
                                }
                            }
                        }
                    }
                // }
            }
            if(list.size() > 0) {
                size += this.getBaseMapper().insertByBatch(trueTableName, list);
            }
        }
        System.out.println("记录数：" + count + "；执行耗时：" + (System.currentTimeMillis() - startTime));
        return size;
    }

    public int clearTable(String tableName) {
        return this.getBaseMapper().clearTable(SyncConst.TABLE_PREFIX + tableName);
    }
}
